import { PageContainer } from '@ant-design/pro-layout'
import { Card, Col, message, Row } from 'antd'
import { useRouter } from 'next/router'
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
import { useIntl } from 'react-intl'
import videojs from 'video.js'
import zhCN from 'video.js/dist/lang/zh-CN.json'

import 'video.js/dist/video-js.css'
import ChatPanel from './components/ChatPanel'
import GiftPanel from './components/GiftPanel'

declare global {
  interface Window {
    VIDEO_SERVER_URL?: string
  }
}

declare module 'video.js' {
  export interface Player {
    tech: (isTech?: boolean) => any
  }
}

type VideoJsPlayer = ReturnType<typeof videojs>
interface VideoJsPlayerOptions {
  controls?: boolean
  autoplay?: boolean
  fluid?: boolean
  language?: string
  sources?: Array<{
    src: string
    type: string
  }>
  errorDisplay?: boolean
  html5?: {
    hls?: {
      overrideNative?: boolean
      withCredentials?: boolean
    }
  }
}

interface VideoJsError extends Error {
  code?: number
}

const LiveRoomPage: React.FC = () => {
  const router = useRouter()
  const { id } = router.query
  const intl = useIntl()

  const videoRef = useRef<HTMLVideoElement>(null)
  const playerRef = useRef<VideoJsPlayer | null>(null)

  const roomId = useMemo(() => {
    if (!id) {
      router.push('/')
      return null
    }
    return Array.isArray(id) ? id[0] : id
  }, [id, router])

  const validateRoomId = (id: string): boolean => {
    return /^[\w-]{6,20}$/.test(id)
  }

  const getVideoSource = useCallback((): string => {
    const serverUrl = window.VIDEO_SERVER_URL
    if (!serverUrl || typeof serverUrl !== 'string') {
      throw new Error('视频服务器地址配置错误')
    }

    try {
      const url = new URL(serverUrl)
      const allowedProtocols = ['http:', 'https:', 'rtmp:']
      if (!allowedProtocols.includes(url.protocol)) {
        throw new Error(`不支持的视频协议: ${url.protocol}`)
      }
      return `${serverUrl}/${roomId}`
    } catch (error) {
      console.error('视频服务器地址解析失败:', error)
      throw new Error('视频服务器地址格式错误')
    }
  }, [roomId])

  const initVideoPlayer = useCallback(async () => {
    if (!roomId || !videoRef.current) return

    try {
      if (!validateRoomId(roomId)) {
        throw new Error('房间ID格式不正确')
      }
      const videoSource = getVideoSource()
      const playerOptions: VideoJsPlayerOptions = {
        controls: true,
        autoplay: true,
        fluid: true,
        language: 'zh-CN',
        sources: [
          {
            src: videoSource,
            type: 'rtmp/flv',
          },
        ],
        errorDisplay: false,
        html5: {
          hls: {
            overrideNative: true,
            withCredentials: true,
          },
        },
      }

      playerRef.current = videojs(videoRef.current, playerOptions, function onPlayerReady() {
        const player = this as VideoJsPlayer
        console.log('播放器初始化成功')

        player.tech(true)?.on('loadedmetadata', () => {
          player.currentTime(0)
          player.play()
        })
      })

      playerRef.current.on('error', (error: unknown) => {
        if (!(error instanceof Error)) {
          console.error('未知播放器错误:', error)
          return
        }
        const err = error as VideoJsError
        console.error('播放器错误:', {
          code: err.code,
          message: err.message,
          stack: err.stack,
        })

        switch (err.code) {
          case 1: // MEDIA_ERR_ABORTED
            message.error('视频播放中断，请检查网络连接')
            break
          case 2: // MEDIA_ERR_NETWORK
            message.error('网络连接失败，请检查网络设置')
            break
          case 3: // MEDIA_ERR_DECODE
            message.error('视频解码失败，请尝试刷新页面')
            break
          case 4: // MEDIA_ERR_SRC_NOT_SUPPORTED
            message.error('视频格式不支持，请联系管理员')
            break
          default:
            message.error('视频播放失败，请稍后重试')
        }

        router.push('/error?code=video_error')
      })

      playerRef.current.on('networkStateChange', () => {
        const networkState = playerRef.current?.networkState()
        switch (networkState) {
          case 0: // NO_SOURCE
            message.warning('无法连接到视频源')
            break
          case 1: // NETWORK_LOADING
            message.info('正在连接视频源...')
            break
          case 2: // NETWORK_IDLE
            message.success('视频连接成功')
            break
        }
      })

      playerRef.current.on('progress', () => {
        try {
          const buffered = playerRef.current?.buffered()
          if (buffered && buffered.length > 0) {
            const bufferedEnd = buffered.end(buffered.length - 1)
            const duration = playerRef.current?.duration() || 0
            if (duration > 0) {
              const bufferedPercent = (bufferedEnd / duration) * 100
              console.log(`视频缓冲进度: ${bufferedPercent.toFixed(2)}%`)
            }
          }
        } catch (error) {
          console.error('缓冲进度计算失败:', error)
        }
      })
    } catch (error) {
      console.error('播放器初始化失败:', error)
      message.error('播放器初始化失败')
      router.push('/error?code=player_init_failed')
    }
  }, [roomId, router, getVideoSource])

  useEffect(() => {
    videojs.addLanguage('zh-CN', zhCN)
  }, [])

  useEffect(() => {
    initVideoPlayer()

    return () => {
      if (playerRef.current) {
        playerRef.current.dispose()
        playerRef.current = null
      }
    }
  }, [initVideoPlayer])

  if (!roomId) {
    return null
  }
  return (
    <PageContainer title={intl.formatMessage({ id: 'live.title' })}>
      <Row gutter={16}>
        <Col span={18}>
          <Card>
            <div data-vjs-player>
              <video
                ref={videoRef}
                className="video-js vjs-big-play-centered"
                style={{ width: '100%', height: '500px' }}
              />
            </div>
          </Card>
        </Col>
        <Col span={6}>
          <ChatPanel roomId={roomId} />
          <GiftPanel roomId={roomId} />
        </Col>
      </Row>
    </PageContainer>
  )
}

export default LiveRoomPage
